package com.zj.juc.study.future;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;

/**
 * @author 自己的名字
 * @version 1.0.0
 * @ClassName FutureTaskNotGoodDemo
 * @Description FutureTask缺点分析
 * @createTime 2024年12月21日 14:17
 */
public class FutureTaskNotGoodDemo {
    public static void main(String[] args) throws Exception {
        avoidConcurrent();
    }

    /**
     * 避免阻塞
     */
    private static void avoidConcurrent() throws Exception{
        FutureTask<String> task = new FutureTask<>(()->{
            System.out.println(Thread.currentThread().getName()+" \t ----- come in");
            //暂停线程
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "t1";
        });
        Thread thread = new Thread(task, "t1");
        thread.start();
        System.out.println(Thread.currentThread().getName()+" main线程去做其他任务了");
        //一般不直接get，因为极易导致阻塞
        //轮询
        String result = "";
        while (true){
            //频繁地轮询会导致系统阻塞而且也不见得能及时地获取返回结果
            if (task.isDone()){
                result = task.get();
                System.out.println(result);
                break;
            }else {
                //不一直轮询，暂停一会，防止加大系统资源占用
                TimeUnit.MILLISECONDS.sleep(500);
                System.out.println("sleep....");
            }
        }

    }

    private static void m1() throws Exception{
        FutureTask<String> task = new FutureTask<>(()->{
            System.out.println(Thread.currentThread().getName()+" \t ----- come in");
            //暂停线程
            try {
                TimeUnit.SECONDS.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "t1";
        });
        Thread thread = new Thread(task, "t1");
        thread.start();

//        String result = task.get();//线程阻塞，会一直等到结果再离开，一般把get放在最后面不影响其他任务
        //因为线程是阻塞的，所以可以设置最大等待时间,如果设置的时间到了还拿不到结果会抛出TimeOutException异常
        String result = task.get(3, TimeUnit.SECONDS);
        System.out.println(result);
        System.out.println(Thread.currentThread().getName()+" main线程去做其他任务了");
    }
}
